SPDX-FileCopyrightText: 2019 Aleksandar Stoimenov & Pâris Lamboray SPDX-FileCopyrightText: 2024 AlICe laboratory https://alicelab.be
SPDX-License-Identifier: GPL-3.0-or-later
import bpy
import randomkicks = 3 = bass frequencies spectrum, snares = 2 = medium frequencies spectrum, hats = 1 = high frequency spectrum
ClappingMusic = [2, 2, 2, 0, 2, 2, 0, 2, 0, 2, 2, 0]  # CLAPPING MUSIC
Reggaeton = [3, 0, 0, 2, 3, 0, 2, 0, 3, 0, 0, 2, 3, 0, 2, 0]  # REGGAETON
AmenBreak = [
    3,
    0,
    3,
    0,
    2,
    0,
    1,
    2,
    1,
    2,
    3,
    3,
    2,
    0,
    1,
    2,
    3,
    0,
    3,
    0,
    2,
    0,
    1,
    2,
    1,
    2,
    3,
    0,
    2,
    0,
    1,
    2,
]  # AMEN BREAK
UkGarage = [
    3,
    0,
    1,
    0,
    2,
    0,
    1,
    0,
    0,
    0,
    3,
    0,
    2,
    0,
    1,
    0,
    3,
    0,
    3,
    0,
    2,
    0,
    1,
    0,
    2,
    0,
    3,
    0,
    2,
    0,
    1,
    0,
]  # UK GARAGE
Trap = [
    3,
    0,
    1,
    0,
    1,
    0,
    1,
    0,
    2,
    0,
    1,
    0,
    1,
    0,
    3,
    0,
    1,
    0,
    2,
    0,
    1,
    0,
    1,
    0,
    2,
    0,
    1,
    0,
    1,
    0,
    1,
    0,
]  # TRAP
Samba = [3, 0, 1, 3, 3, 0, 1, 3, 3, 0, 1, 3, 3, 0, 1, 3]  # SAMBAThis creates a random rythm
fixedvalue = random.randint(1, 16)
RandomMeasure = []
for i in range(fixedvalue * 2):
    RandomMeasure.append(random.randint(0, 3))randomvalue = random.randint(0, 6)
if randomvalue == 0:
    OriginalMeasure = ClappingMusic.copy()
elif randomvalue == 1:
    OriginalMeasure = Reggaeton.copy()
elif randomvalue == 2:
    OriginalMeasure = AmenBreak.copy()
elif randomvalue == 3:
    OriginalMeasure = UkGarage.copy()
elif randomvalue == 4:
    OriginalMeasure = Trap.copy()
elif randomvalue == 5:
    OriginalMeasure = Samba.copy()
else:
    OriginalMeasure = RandomMeasure.copy()Copy of the first measure, this is the second players measure
ChangingMeasure = OriginalMeasure.copy()This list is for rotation values
ListForRotation = []
for i in range(len(OriginalMeasure)):
    ListForRotation.append(0)Shifts the second player measure to the left
def left_shift():
    ChangingMeasure.append(ChangingMeasure[0])
    ChangingMeasure.pop(0)Spawn cubes row and position them vertically in link with the second measure values
def cube_spawn():
    for x, y in zip(ChangingMeasure, range(len(ChangingMeasure))):
        bpy.ops.mesh.primitive_cube_add(location=(0, y, x), size=1)
    item = "MESH"
    bpy.ops.object.select_all(action="DESELECT")
    bpy.ops.object.select_by_type(type=item)
    bpy.ops.transform.translate(value=(1, 0.0, 0.0))Spawn cubes, then shift the partition left
def cube_spawn_left_shift():
    cube_spawn()
    left_shift()Spawn cylinder rows and position them vertically in link with the first measure values
def collones():
    for x, y in zip(OriginalMeasure, range(len(OriginalMeasure))):
        if x > 0:
            bpy.ops.mesh.primitive_cylinder_add(
                location=(0, y, x),
                radius=0.14164971288,
                depth=1,
                rotation=(0, 3.14159 / 2, 0),
            )This is to create a list of cubes, to call them one by one The list goes from Cube.001 to Cube.999
CubeList = ["Cube." + "{0:03}".format(i) for i in range(1000)]
CubeList[0] = "Cube"Here we add Cube.1000 to Cube.9999 to the list
jusquadixmille = ["Cube." + "{0:04}".format(i) for i in range(10000)]
for i in range(1000):
    jusquadixmille.pop(0)
for i in range(9000):
    CubeList.append(jusquadixmille[0])
    jusquadixmille.pop(0)This script is to skip the cube row, it intends to go to the next row for operations
def next_measure():
    for i in range(len(OriginalMeasure)):
        CubeList.pop(0)Select a cube, then rotate it through list values
def rotating(x, y):
    bpy.ops.object.select_all(action="DESELECT")
    bpy.data.objects[x].select_set(True)
    bpy.ops.transform.rotate(value=3.14159 * y / 180, orient_axis="Z")
    bpy.ops.transform.rotate(value=3.14159 * y / 180, orient_axis="X")Rotate all the cubes
def transform_all():
    for x, y in zip(CubeList[0 : len(OriginalMeasure)], ListForRotation):
        rotating(x, y)
    next_measure()
    left_shift()Select a cube, then scale it through list values
def scaling(x, y):
    obj = bpy.context.window.scene.objects[x]
    bpy.context.view_layer.objects.active = obj
    bpy.context.active_object.scale.z = yScale all the cubes
def transform_all_scale():
    for x, y in zip(CubeList[0 : len(OriginalMeasure)], ChangingMeasure):
        scaling(x, y)Spawn cubes and collumns
for i in range(len(OriginalMeasure) + 1):
    collones()
    cube_spawn_left_shift()
for i in range(int(len(OriginalMeasure) / 2 + 1)):
    left_shift()Transform the cubes
ChangingMeasure = OriginalMeasure.copy()
for i in range(len(OriginalMeasure) + 1):
    transform_all_scale()
    transform_all()
    ListForRotation[:] = [i + 90 / (len(OriginalMeasure) / 2) for i in ListForRotation]CubeList = ["Cube." + "{0:03}".format(i) for i in range(1000)]
CubeList[0] = "Cube"
jusquadixmille = ["Cube." + "{0:04}".format(i) for i in range(10000)]
for i in range(1000):
    jusquadixmille.pop(0)
for i in range(9000):
    CubeList.append(jusquadixmille[0])
    jusquadixmille.pop(0)
ChangingMeasure = OriginalMeasure.copy()This is to delete them
def deleting(x, y):
    bpy.ops.object.select_all(action="DESELECT")
    bpy.data.objects[x].select_set(True)
    if y < 1:
        bpy.ops.object.delete()def deleting_all():
    for x, y in zip(CubeList[0 : len(OriginalMeasure)], ChangingMeasure):
        deleting(x, y)
    next_measure()
    left_shift()
for i in range(len(OriginalMeasure) + 1):
    deleting_all()bpy.context.view_layer.objects.active = bpy.context.scene.objects["Cube"]
item = "MESH"
bpy.ops.object.select_all(action="DESELECT")
bpy.ops.object.select_by_type(type=item)
bpy.ops.object.join()
bpy.data.objects["Cube"].dimensions = (10, 10, 10)